package com.fowo.api.sys.service.impl;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fowo.api.sys.entity.SysMessage;
import com.fowo.api.sys.entity.SysMessageTo;
import com.fowo.api.sys.mapper.SysMessageMapper;
import com.fowo.api.sys.mapper.SysMessageToMapper;
import com.fowo.api.sys.model.CreateSysMessage;
import com.fowo.api.sys.model.SysMessageItemVo;
import com.fowo.api.sys.model.SysMessageSearch;
import com.fowo.api.sys.service.SysMessageService;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;

@Service
public class SysMessageServiceImpl extends ServiceImpl<SysMessageMapper, SysMessage> implements SysMessageService {

    @Resource
    private SysMessageToMapper sysMessageToMapper;

    @Override
    public SysMessage getById(Long id) {
        return super.getById(id);
    }

    @Override
    public Page<SysMessageItemVo> searchPage(SysMessageSearch search) {
        return baseMapper.searchPage(search.toPage(), search);
    }

    @Transactional(rollbackFor = Throwable.class)
    @Override
    public boolean create(@Validated CreateSysMessage createSysMessage) {
        SysMessage sysMessage = new SysMessage();
        BeanUtils.copyProperties(createSysMessage, sysMessage);
        sysMessage.setCreateTime(new Date());
        if (save(sysMessage)) {
            for(Long toUserId : createSysMessage.getToUserIds()) {
                SysMessageTo sysMessageTo = new SysMessageTo();
                sysMessageTo.setMessageId(sysMessage.getId());
                sysMessageTo.setDelFlag(false);
                sysMessageTo.setIsRead(false);
                sysMessageTo.setToUserId(toUserId);
                sysMessageToMapper.insert(sysMessageTo);
            }
        }
        return false;
    }

    @Override
    public Long getUnreadCount(Long userId) {
        return sysMessageToMapper.selectCount(Wrappers.<SysMessageTo>query()
                .eq("is_read", false)
                .eq("del_flag", false)
                .eq("to_user_id", userId)
        );
    }

    @Override
    public void updateRead(Long userId, List<Long> messageIds) {
        SysMessageTo updateSysMessageTo = new SysMessageTo();
        updateSysMessageTo.setIsRead(true);
        updateSysMessageTo.setReadTime(new Date());

        sysMessageToMapper.update(updateSysMessageTo, Wrappers.<SysMessageTo>query()
                .eq("is_read", false)
                .eq("del_flag", false)
                .eq("to_user_id", userId)
                .in( messageIds != null, "message_id", messageIds)
        );
    }

    @Override
    public void delete(List<Long> messageIds) {
        SysMessage updateSysMessage = new SysMessage();
        updateSysMessage.setDelFlag(true);

        update(updateSysMessage, Wrappers.<SysMessage>query().in("id", messageIds));
    }

    @Override
    public void deleteByReceiver(Long userId, List<Long> messageIds) {
        SysMessageTo updateSysMessageTo = new SysMessageTo();
        updateSysMessageTo.setDelFlag(true);

        sysMessageToMapper.update(updateSysMessageTo, Wrappers.<SysMessageTo>query()
                .eq("del_flag", false)
                .eq("to_user_id", userId)
                .in( "message_id", messageIds)
        );
    }

    @Override
    public boolean deleteRead(Long userId) {
        baseMapper.deleteRead(userId);
        return true;
    }
}
